package com.telrob.bytevm.vm;

import java.util.List;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;

import com.telrob.bytevm.compile.Instruct;
import com.telrob.bytevm.utils.ToolUtils;

public class VM {
	
	private boolean isBebug=false;
	private boolean isPrint=false;
	private static Scanner scanner=new Scanner(System.in);
	private static LinkedBlockingQueue<Register> queue=new LinkedBlockingQueue<Register>();
	public static void main(String[] args) {
		VM vm=new VM("main.bin");
		vm.run();
	}
	
	public static void addTask(Register task) {
		queue.add(task);
	}
	
	private byte[]code=null;
	public VM(String fileName) {
		code=ToolUtils.loadFile(fileName);
		queue.add(new Register());
	}
	
	
	public void run() {
		List<Instruct> instructList=ToolUtils.register();
		//跳过本地方法表
		int start=ToolUtils.getInt(code, 0);
		//System.err.println("开始:"+start);
		Register R=queue.poll();
		R.PC=start;
		//开始译码
		int count=0;
		while(true) {
			if(queue.size()<0) {
				//System.err.println("system exit");
				System.exit(0);
			}
			byte opt=code[R.PC];
			//System.err.println(R.PC+","+code.length+","+opt);
			if(isPrint) {
				System.err.println(R);
				System.err.printf("operator:%08X\r\n",opt);
			}
			boolean isOpt=false;
			for(Instruct ins:instructList) {
				if(ins.isRun(opt)>=0) {
					//System.err.println(ins.getClass());
					ins.parseRun(R, opt, code);
					isOpt=true;
					break;
				}
			}
			if(isOpt==false) {
				//System.err.println("system exit"+opt);
				System.exit(0);
			}
			if(isBebug) {
				scanner.nextLine();
			}
			count++;
			if(count>=10) {
				count=0;
				queue.add(R);
				R=queue.poll();
			}
		}
	}
}
